﻿// Copyright (c) Inossem. All rights reserved.
// Licensed under the LGPL-3.0 license. See LICENSE file in the project root for full license information.
using DWF.Studio.Custom;
using DWF.Studio.Host;
using DWF.Studio.Project;
using DWF.Studio.ScriptEngine.IPC.Msg;
using DWF.Studio.Script;
using DWF.Studio.Script.Excutor;
using DWF.Studio.Script.Implementation;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using DWF.Studio.ISerivces;
using DWF.Studio.Services;
using DWF.Studio.Models;
using WpfMessageBoxLibrary;
using DWF.Studio.ScriptEngine.IPC.WorkFlow;
using ICSharpCode.AvalonEdit;
using System.Text.RegularExpressions;
using System.Threading;
using ICSharpCode.AvalonEdit.Snippets;
using DWF.Studio.ScriptEngine.IPC;
using System.Windows.Threading;
using DWF.Studio.Share.Utils;
//using ActiproSoftware.Windows.Extensions;
using DWF.Studio.Share.Log;

namespace DWF.Studio.Views
{
    /// <summary>
    /// 设计区域控件
    /// </summary>
    public partial class UCtrlDesignRegion : UserControl
    {
        /// <summary>
        /// 临时缓存 在依赖包更改是 保存显示的脚本 以便更改完成后的恢复显示
        /// </summary>
        private List<Tuple<ScriptBase, bool>> _tempScriptCache = null;

        private IExecutionService _executionService = null;

        private IProjectSettingService _projectSettingService = null;

        private ISearchService _searchService = null;

        private IProjectParamDetailSerivce _projectParamDetailSerivce = null;

        private DWF.Studio.BaseService.Contract.Studio.IWindowService _windowService = null;

        private double _lastButtomTabitemHight = 300;

        private ObservableCollection<Breakpoint> _obsBreakPoints = new ObservableCollection<Breakpoint>();
        private List<TrackingInfo> enumTrackingInfos = new List<TrackingInfo>();

        public UCtrlDesignRegion()
        {
            InitializeComponent();

            if (!DesignerProperties.GetIsInDesignMode(this))
            {
                init();
            }
        }

        /// <summary>
        /// 初始化
        /// </summary>
        private void init()
        {
            _tempScriptCache = new List<Tuple<ScriptBase, bool>>();
            _executionService = ExecutionService.Instance;
            _projectSettingService = new ProjectSettingService();
            _searchService = new SearchService();
            _projectParamDetailSerivce = new ProjectParamDetailSerivce();
            _windowService = new DWF.Studio.BaseService.WindowService();
            this.lvBreakPoint.ItemsSource = _obsBreakPoints;

            #region 注册操作事件
            GlobalActionHandler.BreakPointToggle += toggleBreakPoint;

            GlobalActionHandler.ScriptDebug += debugScript;
            GlobalActionHandler.ScriptDebugByStep += debugByStepScript;

            GlobalActionHandler.ScriptRun += scriptRun;
            GlobalActionHandler.AllScriptRun += allScriptRun;
            GlobalActionHandler.ScriptStop += scriptStop;
            GlobalActionHandler.ScriptSave += scriptSave;
            GlobalActionHandler.AllScriptSave += allScriptSave;
            GlobalActionHandler.ScriptAutoSave += scriptAutoSave;
            GlobalActionHandler.ScriptShow += showScript;
            GlobalActionHandler.ScriptRename += renameScript;
            GlobalActionHandler.ScriptDelete += deleteScript;
            GlobalActionHandler.ProjectPreclose += precloseProject;
            GlobalActionHandler.ProjectClosing += closeProject;
            GlobalActionHandler.ProjectOpened += openedProject;

            GlobalActionHandler.ValidateScript += validateScripts;

            GlobalActionHandler.SetPutParam += setPutParam;
            GlobalActionHandler.SetPutParams += setPutParams;
            GlobalActionHandler.LoadPutParam += loadPutParam;

            GlobalActionHandler.SnippetScriptShow += showSnippetScript;

            GlobalActionHandler.AddActivityToWorkflow += addActivityToWorkflow;
            GlobalActionHandler.GetRootActivityCode += getRootActivityCode;
            GlobalActionHandler.GetRootActivityTypeName += getRootActivityTypeName;
            GlobalActionHandler.SetActivityByCode += setActivityByCode;

            GlobalActionHandler.PackagePrechange += packagePrechange;
            GlobalActionHandler.PackageChanged += packageChanged;

            GlobalActionHandler.Cut += cut;
            GlobalActionHandler.Copy += copy;
            GlobalActionHandler.Paste += paste;
            GlobalActionHandler.Undo += undo;
            GlobalActionHandler.Redo += redo;
            GlobalActionHandler.Find += find;
            GlobalActionHandler.Replace += replace;
            GlobalActionHandler.SelectionActivity += focusActivityByIdRef;
            GlobalActionHandler.Notes += notes;
            GlobalActionHandler.CancelNotes += cancelNotes;

            GlobalActionHandler.MsgOutput += outputMsg;
            Console.SetOut(new OutputWriter(excuteOutput));

            GlobalActionHandler.SwitchLogPanel += btnMiniOrMaxLogTab;
            #endregion

            #region 注册执行器事件

            ScriptExecutorSet.WorkflowExcutor.ExecuteTrack = excuteTrace;
            ScriptExecutorSet.WorkflowExcutor.ExecuteCompleted = excuteCompleted;
            ScriptExecutorSet.WorkflowExcutor.ExecuteOnUnhandledException = excuteOnUnhandledException;
            ScriptExecutorSet.WorkflowExcutor.DebugTrack = debugTrack;
            ScriptExecutorSet.WorkflowExcutor.HitBreakpoint = hitBreakpoint;
            ScriptExecutorSet.WorkflowExcutor.ExecuteEnd = executeEnd;
            ScriptExecutorSet.WorkflowExcutor.ExecuteStart = executeStart;
            ScriptExecutorSet.WorkflowExcutor.SubScriptExecuteStart = subScriptExecuteStart;
            ScriptExecutorSet.WorkflowExcutor.SubScriptExecuteEnd = subScriptExecuteEnd;
            #endregion
        }

        /// <summary>
        /// 点击 tab上关闭
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CloseTab_Click(object sender, RoutedEventArgs e)
        {
            var menuItem = WPFExtensionMethods.VisualUpwardSearch<CustomTabItem>(e.OriginalSource as DependencyObject) as CustomTabItem;
            var filepath = "";
            if (menuItem == null)
                filepath = (sender as Button).Tag.ToString();
            else
                filepath = menuItem.FilePath.ToString();
            foreach (TabItem tabItem in this.tabCtrlFiles.Items)
            {
                var script = (ScriptBase)tabItem.Tag;
                if (script != null)
                {
                    
                    if (script.FilePath.ToString() == filepath)
                    {
                        if (script.IsEditorContentChanged)
                        {
                            var msgProperties = new WpfMessageBoxProperties()
                            {
                                Button = MessageBoxButton.YesNoCancel,
                                ButtonYesText = LocalizationProvider.GetLocalizedString("MessageBox_Button_Yes"),
                                ButtonNoText = LocalizationProvider.GetLocalizedString("MessageBox_Button_No"),
                                ButtonCancelText = LocalizationProvider.GetLocalizedString("MessageBox_Button_Cancel"),
                                Image = MessageBoxImage.Question,
                                Text = LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Msg_SaveFile"),
                                Title = LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Caption_SaveFile"),
                            };

                            Window owner = Window.GetWindow(this);
                            MessageBoxResult dlgResult = WpfMessageBox.Show(owner, ref msgProperties);

                            if (dlgResult == MessageBoxResult.Yes)
                            {
                                string msg;
                                var issuccess = script.TrySave(out msg);
                                if (issuccess)
                                {
                                    var breakpoints = script.GetBreakpoints();
                                    _projectSettingService.RefreshBreakpoints(script.FilePath, breakpoints);
                                }
                                else
                                {
                                    var msgProperties1 = new WpfMessageBoxProperties()
                                    {
                                        Button = MessageBoxButton.OK,
                                        ButtonOkText = LocalizationProvider.GetLocalizedString("MessageBox_Button_OK"),
                                        Image = MessageBoxImage.Error,
                                        Text = LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Msg_SaveFile_Error"),
                                        Title = LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Caption_SaveFile"),
                                    };
                                    WpfMessageBox.Show(owner, ref msgProperties1);
                                }
                            }
                            else if (dlgResult == MessageBoxResult.Cancel)
                            {
                                return;
                            }
                        }

                        this.tabCtrlFiles.Items.Remove(tabItem);
                        script.Dispose();//释放脚本   

                        break;
                    }
                }
            }

            if (this.tabCtrlFiles.Items.Count == 0)
            {
                GlobalActionHandler.ScriptSelected?.Invoke(new TagEventArgs<ScriptBase>(null));
            }
        }

        /// <summary>
        /// 显示控制台输出信息
        /// </summary>
        /// <param name="c"></param>
        private void excuteOutput(string content)
        {
            //使用异步，避免在安装包时，出现死锁情况。 andy 2019.03.26
            this.Dispatcher.InvokeAsync(() =>
            {
                var lineCount = Regex.Matches(consoleOutput.Text, System.Environment.NewLine).Count;
                if (lineCount > 500)
                {
                    var lines = (from item in consoleOutput.Text.Split('\n') select item.Trim()).Skip(100).ToArray();
                    consoleOutput.Text = string.Join(Environment.NewLine, lines.ToArray());
                }

                consoleOutput.AppendText(content);
                consoleOutput.ScrollToEnd();
            }, System.Windows.Threading.DispatcherPriority.Background);
        }

        /// <summary>
        /// 执行追踪
        /// </summary>
        /// <param name="e"></param>
        private void excuteTrace(ScriptExecuteTrackEventArgs e)
        {
            excuteLog(e.TrackData);
        }

        private void excuteAbort(ScriptExcuteAbortedEventArgs e)
        {
            excuteLog(e.Reason);
        }

        /// <summary>
        /// 未处理异常
        /// </summary>
        /// <param name="e"></param>
        private void excuteOnUnhandledException(ScriptExcuteUnhandledExceptionEventArgs e)
        {
            excuteLog(e.ToString(), true);
            trackTerminalScript(e);
        }

        private void excuteLog(string msg, bool isException = false)
        {
            this.Dispatcher.InvokeAsync(() =>
            {
                TextRange textRange = new TextRange(consoleExecutionLog.Document.ContentStart, consoleExecutionLog.Document.ContentEnd);

                var lineCount = Regex.Matches(textRange.Text, System.Environment.NewLine).Count;
                if (lineCount > 500)
                {
                    var lines = (from item in textRange.Text.Split('\n') select item.Trim()).Skip(100).Where(s => !string.IsNullOrEmpty(s)).ToArray();
                    textRange.Text = "";
                    var lineText = string.Join(Environment.NewLine, lines);
                    var paragraph = new Paragraph(new Run(lineText) { Foreground = Brushes.Black });
                    paragraph.LineHeight = 3;
                    consoleExecutionLog.Document.Blocks.Add(paragraph);
                }
                if (isException)
                {
                    var paragraph = new Paragraph(new Run(msg) { Foreground = Brushes.Red });
                    paragraph.LineHeight = 3;
                    consoleExecutionLog.Document.Blocks.Add(paragraph);
                }
                else
                {
                    var paragraph = new Paragraph(new Run(msg) { Foreground = Brushes.Black });
                    paragraph.LineHeight = 3;
                    consoleExecutionLog.Document.Blocks.Add(paragraph);
                    //consoleExecutionLog.AppendText(msg + Environment.NewLine);
                }
                consoleExecutionLog.ScrollToEnd();
            }, System.Windows.Threading.DispatcherPriority.Background);
        }

        private void excuteCompleted(ScriptExcuteCompletedEventArgs e)
        {
            if (e.Outputs != null)
            {
                foreach (var pair in e.Outputs)
                {
                    Console.WriteLine(String.Format("name:{0} --- value:{1}", pair.Key, pair.Value));
                }
            }

            if (GlobalActionHandler.SetStatusBarMsg != null)
            {
                GlobalActionHandler.SetStatusBarMsg(new TagEventArgs<string>(LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_StatusBar_Msg_ExcuteCompleted")));
            }
        }

        /// <summary>
        /// 显示脚本
        /// </summary>
        /// <param name="e"></param>
        private void showScript(TagEventArgs<ProjectFile> e)
        {
            if (e.Tag.Extension != StaticResource.XamlExtension)
            {
                return;
            }

            this.showScript(e.Tag);
        }

        /// <summary>
        /// 重命名脚本
        /// </summary>
        /// <param name="e"></param>
        private void renameScript(TagEventArgs<ProjectFile, string> e)
        {
            var fullName = e.Tag2;
            foreach (var item in this.tabCtrlFiles.Items)
            {
                var tabitem = item as TabItem;
                if (tabitem != null)
                {
                    var script = (ScriptBase)tabitem.Tag;
                    if (fullName == script.FilePath)
                    {
                        tabitem.IsSelected = true;
                        script.Rename(fullName, e.Tag1.Name);
                        tabitem.Header = script.FileName;

                        break;
                    }
                }
            }

            _projectSettingService.ChangeFilePath(fullName, e.Tag1.FullName);
        }

        /// <summary>
        /// 删除脚本
        /// </summary>
        /// <param name="e"></param>
        private void deleteScript(TagEventArgs<ProjectFile> e)
        {
            var file = e.Tag;
            TabItem itemDel = null;
            foreach (var item in this.tabCtrlFiles.Items)
            {
                var tabitem = item as TabItem;
                if (tabitem != null)
                {
                    var script = (ScriptBase)tabitem.Tag;
                    if (file.FullName == script.FilePath)
                    {
                        itemDel = tabitem;
                        break;
                    }
                }
            }

            if (itemDel != null)
            {
                this.tabCtrlFiles.Items.Remove(itemDel);
            }

            _projectSettingService.RemoveBreakpoints(file.FullName);
            loadLvBreakPoint(EventArgs.Empty);
        }

        /// <summary>
        /// 运行脚本
        /// </summary>
        /// <param name="e"></param>
        private void scriptRun(EventArgs e)
        {
            var status = _executionService.GetCurrentStatus();

            if (status == ExecuteStatus.Idle)
            {
                var issuccess = allScriptSave(e);
                if (!issuccess)
                {
                    return;
                }

                consoleOutput.Clear();
                consoleExecutionLog.Document.Blocks.Clear();

                var selectItem = this.tabCtrlFiles.SelectedItem as CustomTabItem;
                if (selectItem != null)
                {
                    var script = selectItem.Tag as ScriptBase;
                    if (script != null)
                    {
                        string msg;
                        if (script.Validate(out msg))
                        {
                            if (GlobalActionHandler.SetStatusBarMsg != null)
                            {
                                GlobalActionHandler.SetStatusBarMsg(new TagEventArgs<string>(LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_StatusBar_Msg_ScriptRun")));
                            }

                            _executionService.Execute(script);
                        }
                        else
                        {
                            GlobalActionHandler.ValidateScript?.Invoke(new TagEventArgs<string>(script.FilePath));
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 停止运行脚本
        /// </summary>
        /// <param name="e"></param>
        private void scriptStop(EventArgs e)
        {
            _executionService.Stop();
        }

        /// <summary>
        /// 整体运行
        /// </summary>
        /// <param name="e"></param>
        private void allScriptRun(EventArgs e)
        {
            var status = _executionService.GetCurrentStatus();

            if (status == ExecuteStatus.Idle)
            {
                var issuccess = allScriptSave(e);
                if (!issuccess)
                {
                    return;
                }

                consoleOutput.Clear();
                consoleExecutionLog.Document.Blocks.Clear();

                ScriptBase startScript = null;
                foreach (var item in this.tabCtrlFiles.Items)
                {
                    var tabitem = item as CustomTabItem;
                    if (tabitem != null)
                    {
                        var script = (ScriptBase)tabitem.Tag;

                        if (script.IsStart)//是否是启动项
                        {
                            tabitem.IsSelected = true;//展示此脚本
                            startScript = script;
                        }
                    }
                }

                if (startScript != null)
                {
                    string msg;
                    if (startScript.Validate(out msg))
                    {
                        if (GlobalActionHandler.SetStatusBarMsg != null)
                        {
                            GlobalActionHandler.SetStatusBarMsg(new TagEventArgs<string>(LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_StatusBar_Msg_ScriptRun")));
                        }

                        _executionService.Execute(startScript);
                    }
                    else
                    {
                        GlobalActionHandler.ValidateScript?.Invoke(new TagEventArgs<string>(startScript.FilePath));
                    }
                }
                else
                {
                    startScript = this.showScript(ProjectManager.Instance.CurrentProject.StartFile);

                    if (startScript != null)
                    {
                        string msg;
                        if (startScript.Validate(out msg))
                        {
                            if (GlobalActionHandler.SetStatusBarMsg != null)
                            {
                                GlobalActionHandler.SetStatusBarMsg(new TagEventArgs<string>(LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_StatusBar_Msg_ScriptRun")));
                            }
                            _executionService.Execute(startScript);
                        }
                        else
                        {
                            GlobalActionHandler.ValidateScript?.Invoke(new TagEventArgs<string>(startScript.FilePath));
                            //excuteTrace(new ScriptExecuteTrackEventArgs(msg));
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 保存脚本
        /// </summary>
        /// <param name="e"></param>
        private bool scriptSave(EventArgs e)
        {
            bool result = false;
            var tabitem = this.tabCtrlFiles.SelectedItem as CustomTabItem;
            if (tabitem != null)
            {
                if (tabitem.IsContentChanged)
                {
                    var script = tabitem.Tag as ScriptBase;
                    if (script != null)
                    {
                        string msg;
                        result = script.TrySave(out msg);
                        if (result)
                        {
                            var breakpoints = script.GetBreakpoints();
                            _projectSettingService.RefreshBreakpoints(script.FilePath, breakpoints);

                            tabitem.IsContentChanged = false;
                        }
                        else
                        {
                            excuteTrace(new ScriptExecuteTrackEventArgs(msg));
                            var msgProperties1 = new WpfMessageBoxProperties()
                            {
                                Button = MessageBoxButton.OK,
                                ButtonOkText = LocalizationProvider.GetLocalizedString("MessageBox_Button_OK"),
                                Image = MessageBoxImage.Error,
                                Text = LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Msg_SaveFile_Error"),
                                Title = LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Caption_SaveFile"),
                            };
                            Window owner = Window.GetWindow(this);
                            WpfMessageBox.Show(owner, ref msgProperties1);
                        }
                    }
                }
            }

            if (result)
            {
                if (GlobalActionHandler.SetStatusBarMsg != null)
                {
                    GlobalActionHandler.SetStatusBarMsg(new TagEventArgs<string>(LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_StatusBar_Msg_SaveFile")));
                }
            }
            loadLvBreakPoint(EventArgs.Empty);
            return result;
        }

        /// <summary>
        /// 保存全部脚本
        /// </summary>
        /// <param name="e"></param>
        private bool allScriptSave(EventArgs e)
        {
            bool result = true;
            foreach (var item in this.tabCtrlFiles.Items)
            {
                var tabitem = item as CustomTabItem;
                if (tabitem != null)
                {
                    if (tabitem.IsContentChanged)
                    {
                        var script = (ScriptBase)tabitem.Tag;
                        if (script != null)
                        {
                            string msg;
                            result = script.TrySave(out msg);
                            if (result)
                            {
                                var breakpoints = script.GetBreakpoints();
                                _projectSettingService.RefreshBreakpoints(script.FilePath, breakpoints);

                                tabitem.IsContentChanged = false;
                            }
                            else
                            {
                                excuteTrace(new ScriptExecuteTrackEventArgs(msg));
                                var msgProperties1 = new WpfMessageBoxProperties()
                                {
                                    Button = MessageBoxButton.OK,
                                    ButtonOkText = LocalizationProvider.GetLocalizedString("MessageBox_Button_OK"),
                                    Image = MessageBoxImage.Error,
                                    Text = LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Msg_SaveFile_Error"),
                                    Title = LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Caption_SaveFile"),
                                };
                                Window owner = Window.GetWindow(this);
                                WpfMessageBox.Show(owner, ref msgProperties1);

                                break;
                            }
                        }
                    }
                }
            }

            if (result)
            {
                if (GlobalActionHandler.SetStatusBarMsg != null)
                {
                    GlobalActionHandler.SetStatusBarMsg(new TagEventArgs<string>(LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_StatusBar_Msg_SaveAllFiles")));
                }
            }
            loadLvBreakPoint(EventArgs.Empty);
            return result;
        }

        /// <summary>
        /// 保存全部脚本
        /// </summary>
        /// <param name="e"></param>
        private void scriptAutoSave(EventArgs e)
        {
            foreach (var item in this.tabCtrlFiles.Items)
            {
                var tabitem = item as CustomTabItem;
                if (tabitem != null)
                {
                    if (tabitem.IsContentChanged)
                    {
                        var script = (ScriptBase)tabitem.Tag;
                        if (script != null)
                        {
                            string msg;
                            var result = script.TrySave(out msg);
                            if (result)
                            {
                                var breakpoints = script.GetBreakpoints();
                                _projectSettingService.RefreshBreakpoints(script.FilePath, breakpoints);

                                tabitem.IsContentChanged = false;
                            }
                        }
                    }
                }
            }
            loadLvBreakPoint(EventArgs.Empty);
        }

        private TextEditor getCurrentTextEditor()
        {
            TextEditor currentEditor = null;
            TabItem selectItem = this.tabCtrlFiles.SelectedItem as TabItem;
            if (selectItem != null)
            {
                var script = selectItem.Tag as ScriptBase;
                if (script != null)
                {
                    currentEditor = script.ScriptEditor as TextEditor;
                }
            }

            return currentEditor;
        }

        /// <summary>
        /// 工程打开完成
        /// </summary>
        /// <param name="e"></param>
        private void openedProject(EventArgs e)
        {
            if (ProjectManager.Instance != null && ProjectManager.Instance.CurrentProject != null)
            {
                WindowLoading.SetContent(LocalizationProvider.GetLocalizedString("WindowLoading_Msg_OpenFile"), ProjectManager.Instance.CurrentProject.StartFile.DisplayName);
                this.showScript(ProjectManager.Instance.CurrentProject.StartFile);
            }
        }

        /// <summary>
        /// 关闭工程
        /// </summary>
        /// <param name="e"></param>
        private void closeProject(EventArgs e)
        {
            foreach (TabItem tabItem in this.tabCtrlFiles.Items)
            {
                var script = tabItem.Tag as ScriptBase;
                if (script != null)
                {
                    script.Dispose();
                }
            }

            this.tabCtrlFiles.Items.Clear();
            this.consoleOutput.Clear();
            this.consoleExecutionLog.Document.Blocks.Clear();
        }

        /// <summary>
        /// 关闭工程
        /// </summary>
        /// <param name="e"></param>
        private void precloseProject(CancelEventArgs cea)
        {
            closeSaveNotice(cea);
            closeExecutingNotice(cea);
        }

        /// <summary>
        /// 依赖包更改
        /// </summary>
        /// <param name="e"></param>
        private void packagePrechange(EventArgs e)
        {
            if (this.tabCtrlFiles.Items.Count > 0)
            {
                foreach (var oitem in this.tabCtrlFiles.Items)
                {
                    var tabitem = oitem as CustomTabItem;
                    if (tabitem != null)
                    {
                        tabitem.IsContentChanged = false;
                        var scriptInfo = tabitem.Tag as ScriptBase;
                        if (scriptInfo != null)
                        {
                            string msg;
                            var issuccess = scriptInfo.TrySave(out msg);
                            if (issuccess)
                            {
                                var breakpoints = scriptInfo.GetBreakpoints();
                                _projectSettingService.RefreshBreakpoints(scriptInfo.FilePath, breakpoints);
                            }

                            if (scriptInfo is WorkflowScript)
                            {
                                ((WorkflowScript)scriptInfo).DisposeView();//释放试图
                            }
                            _tempScriptCache.Add(new Tuple<ScriptBase, bool>(scriptInfo, tabitem.IsSelected));
                        }
                    }
                }

                this.tabCtrlFiles.Items.Clear();
            }

            this.consoleOutput.Clear();
            this.consoleExecutionLog.Document.Blocks.Clear();
        }

        /// <summary>
        /// 依赖包更改完成
        /// </summary>
        /// <param name="e"></param>
        private void packageChanged(EventArgs e)//???Carl 卸载包有个偶发性空异常
        {
            foreach (var tuple in this._tempScriptCache)
            {
                var workflowScript = tuple.Item1 as WorkflowScript;
                if (workflowScript != null)//如果是工作流脚本 需要从新加载执行器
                {
                    var breakpoints = _projectSettingService.GetBreakpoints(workflowScript.FilePath);
                    workflowScript.Reload(breakpoints);
                }

                var item = new CustomTabItem() { IsSelected = tuple.Item2, Tag = tuple.Item1, Header = tuple.Item1.FileName, Content = tuple.Item1.ScriptEditor, IsReadOnly = tuple.Item1.IsReadOnly, FilePath = tuple.Item1.FilePath.ToString() };
       
                if (workflowScript != null)
                {
                    workflowScript.EditorContentChanged = (ea) => { item.IsContentChanged = true; };
                }
                this.tabCtrlFiles.Items.Add(item);
            }
            this.setScriptReadOnly(false);
            _tempScriptCache.Clear();
        }

        /// <summary>
        /// 在激活的脚本中添加活动
        /// </summary>
        /// <param name="parentCode"></param>
        /// <param name="activityTypeName"></param>
        /// <param name="param"></param>
        private string addActivityToWorkflow(string parentCode, string activityTypeName, IDictionary<string, object> param)
        {
            string result = null;
            TabItem selectItem = this.tabCtrlFiles.SelectedItem as TabItem;
            if (selectItem != null)
            {
                var script = selectItem.Tag as WorkflowScript;
                if (script != null)
                {
                    result = script.AddActivityByParentCode(parentCode, activityTypeName, param);
                }
            }

            return result;
        }

        private string getRootActivityCode()
        {
            string result = null;
            TabItem selectItem = this.tabCtrlFiles.SelectedItem as TabItem;
            if (selectItem != null)
            {
                var script = selectItem.Tag as WorkflowScript;
                if (script != null)
                {
                    result = script.GetRootActivityCode();
                }
            }

            return result;
        }

        private string getRootActivityTypeName()
        {
            string result = null;
            TabItem selectItem = this.tabCtrlFiles.SelectedItem as TabItem;
            if (selectItem != null)
            {
                var script = selectItem.Tag as WorkflowScript;
                if (script != null)
                {
                    result = script.GetRootActivityTypeName();
                }
            }

            return result;
        }

        public void setActivityByCode(string activityCode, IDictionary<string, object> param)
        {
            TabItem selectItem = this.tabCtrlFiles.SelectedItem as TabItem;
            if (selectItem != null)
            {
                var script = selectItem.Tag as WorkflowScript;
                if (script != null)
                {
                    script.SetActivityByCode(activityCode, param);
                }
            }
        }

        private void TabCtrlFiles_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count > 0)
            {
                var item = e.AddedItems[0] as TabItem;
                if (item != null)
                {
                    //调试切换文件时获取焦点 Oliver add 2021-06-25
                    //可见元素的布局刷新
                    UpdateLayout();
                    //焦点定位到当前Tab控件
                    (item as CustomTabItem).Focus();

                    var script = item.Tag as ScriptBase;
                    GlobalActionHandler.ScriptSelected?.Invoke(new TagEventArgs<ScriptBase>(script));
                    script.ScriptEditor.Refresh();
                }
            }
        }

        private void ConsoleExecutionLogMenuItem1_Click(object sender, RoutedEventArgs e)
        {
            consoleExecutionLog.Document.Blocks.Clear();
        }

        private void ConsoleOutputMenuItem1_Click(object sender, RoutedEventArgs e)
        {
            consoleOutput.Clear();
        }

        private void cut(EventArgs args)
        {
            TabItem selectItem = this.tabCtrlFiles.SelectedItem as TabItem;
            if (selectItem != null)
            {
                var script = selectItem.Tag as ScriptBase;
                if (script != null)
                {
                    script.Cut();
                }
            }
        }

        private void copy(EventArgs args)
        {
            TabItem selectItem = this.tabCtrlFiles.SelectedItem as TabItem;
            if (selectItem != null)
            {
                var script = selectItem.Tag as ScriptBase;
                if (script != null)
                {
                    script.Copy();
                }
            }
        }

        private void paste(EventArgs args)
        {
            TabItem selectItem = this.tabCtrlFiles.SelectedItem as TabItem;
            if (selectItem != null)
            {
                var script = selectItem.Tag as ScriptBase;
                if (script != null)
                {
                    script.Paste();
                }
            }
        }

        private void undo(EventArgs args)
        {
            TabItem selectItem = this.tabCtrlFiles.SelectedItem as TabItem;
            if (selectItem != null)
            {
                var script = selectItem.Tag as ScriptBase;
                if (script != null)
                {
                    script.Undo();
                }
            }
            loadLvBreakPoint(EventArgs.Empty);
        }

        private void redo(EventArgs args)
        {
            TabItem selectItem = this.tabCtrlFiles.SelectedItem as TabItem;
            if (selectItem != null)
            {
                var script = selectItem.Tag as ScriptBase;
                if (script != null)
                {
                    script.Redo();
                }
            }
            loadLvBreakPoint(EventArgs.Empty);
        }

        private void find(EventArgs args)
        {
            TabItem selectItem = this.tabCtrlFiles.SelectedItem as TabItem;
            if (selectItem != null)
            {
                var script = selectItem.Tag as ScriptBase;
                if (script != null)
                {
                    script.Find();
                }
                ProjectFile file = new ProjectFile()
                {
                    Name = script.FileName,
                    DisplayName = script.FileName,
                    FullName = script.FilePath,
                };
                if (file.Extension == StaticResource.XamlExtension)
                {
                    GlobalActionHandler.FindSearchText?.Invoke(EventArgs.Empty);
                }
            }
        }

        /// <summary>
        /// 获取焦点目标
        /// </summary>
        /// <param name="idRef"></param>
        private void focusActivityByIdRef(TagEventArgs<string, string, string> tag)
        {
            Tuple<ScriptBase, bool> script = null;

            var projectFile = ProjectManager.Instance.GetProjectFile(tag.Tag1);
            if (projectFile != null)
            {
                script = loadScript(projectFile);
            }

            if (script.Item1 != null)
            {
                showScript(script.Item1);
            }

            if (script.Item1 != null && !String.IsNullOrWhiteSpace(tag.Tag2))
            {
                _searchService.FocusActivityByIdRef(script.Item1, tag.Tag2);
            }
        }

        private void replace(EventArgs args)
        {
            TabItem selectItem = this.tabCtrlFiles.SelectedItem as TabItem;
            if (selectItem != null)
            {
                var script = selectItem.Tag as ScriptBase;
                if (script != null)
                {
                    script.Replace();
                }
            }
        }

        private void notes(EventArgs args)
        {
            TabItem selectItem = this.tabCtrlFiles.SelectedItem as TabItem;
            if (selectItem != null)
            {
                var script = selectItem.Tag as ScriptBase;
                if (script != null)
                {
                    script.Notes();
                }
            }
        }

        private void cancelNotes(EventArgs args)
        {
            TabItem selectItem = this.tabCtrlFiles.SelectedItem as TabItem;
            if (selectItem != null)
            {
                var script = selectItem.Tag as ScriptBase;
                if (script != null)
                {
                    script.CancelNotes();
                }
            }
        }

        private void toggleBreakPoint(EventArgs e)
        {
            TabItem selectItem = this.tabCtrlFiles.SelectedItem as TabItem;
            if (selectItem != null)
            {
                var script = selectItem.Tag as ScriptBase;
                if (script != null)
                {
                    script.ToggleBreakPoint();
                }
            }
            GlobalActionHandler.BreakPointFresh?.Invoke(EventArgs.Empty);
        }

        private void debugScript(EventArgs e)
        {
            var status = _executionService.GetCurrentStatus();

            if (status == ExecuteStatus.Idle)
            {
                var issuccess = allScriptSave(e);
                if (!issuccess)
                {
                    return;
                }

                consoleOutput.Clear();
                consoleExecutionLog.Document.Blocks.Clear();

                TabItem selectItem = this.tabCtrlFiles.SelectedItem as TabItem;
                if (selectItem != null)
                {
                    var script = selectItem.Tag as ScriptBase;
                    if (script != null)
                    {
                        string msg;
                        if (script.Validate(out msg))
                        {
                            _executionService.Debug(script);
                        }
                        else
                        {
                            GlobalActionHandler.ValidateScript?.Invoke(new TagEventArgs<string>(script.FilePath));
                        }
                    }
                }
            }
            else
            {
                _executionService.Continue();
                clearScriptCurrentLocation();
            }
        }

        private void debugByStepScript(EventArgs e)
        {
            var status = _executionService.GetCurrentStatus();

            if (status == ExecuteStatus.Idle)
            {
                var issuccess = allScriptSave(e);
                if (!issuccess)
                {
                    return;
                }

                consoleOutput.Clear();
                consoleExecutionLog.Document.Blocks.Clear();

                TabItem selectItem = this.tabCtrlFiles.SelectedItem as TabItem;
                if (selectItem != null)
                {
                    var script = selectItem.Tag as ScriptBase;
                    if (script != null)
                    {
                        string msg;
                        if (script.Validate(out msg))
                        {
                            _executionService.DebugByStep(script);
                        }
                        else
                        {
                            GlobalActionHandler.ValidateScript?.Invoke(new TagEventArgs<string>(script.FilePath));
                        }
                    }
                }
            }
            else
            {
                _executionService.DebugByStep();
            }
        }

        private void closeSaveNotice(CancelEventArgs cea)
        {
            if (cea.Cancel)
            {
                return;
            }

            var hasChangeScripts = false;
            foreach (TabItem tabItem in this.tabCtrlFiles.Items)
            {
                var script = (ScriptBase)tabItem.Tag;
                if (script != null)
                {
                    if (script.IsEditorContentChanged)
                    {
                        hasChangeScripts = true;
                        break;
                    }
                }
            }

            if (hasChangeScripts)
            {
                var msgProperties = new WpfMessageBoxProperties()
                {
                    Button = MessageBoxButton.YesNoCancel,
                    ButtonYesText = LocalizationProvider.GetLocalizedString("MessageBox_Button_Yes"),
                    ButtonNoText = LocalizationProvider.GetLocalizedString("MessageBox_Button_No"),
                    ButtonCancelText = LocalizationProvider.GetLocalizedString("MessageBox_Button_Cancel"),
                    Image = MessageBoxImage.Question,
                    Text = LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Msg_CloseFile_SaveFileNotice"),
                    Title = LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Caption_CloseFile_SaveFileNotice"),
                };

                Window owner = Window.GetWindow(this);
                MessageBoxResult dlgResult = WpfMessageBox.Show(owner, ref msgProperties);

                if (dlgResult == MessageBoxResult.Yes)
                {
                    allScriptSave(EventArgs.Empty);
                }
                else if (dlgResult == MessageBoxResult.Cancel)
                {
                    cea.Cancel = true;
                }
            }
        }

        private void closeExecutingNotice(CancelEventArgs cea)
        {
            var status = _executionService.GetCurrentStatus();
            if (status != ExecuteStatus.Idle)
            {
                var msgProperties = new WpfMessageBoxProperties()
                {
                    Button = MessageBoxButton.YesNo,
                    ButtonYesText = LocalizationProvider.GetLocalizedString("MessageBox_Button_Yes"),
                    ButtonNoText = LocalizationProvider.GetLocalizedString("MessageBox_Button_No"),
                    Image = MessageBoxImage.Question,
                    Text = LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Msg_CloseApp_ExecutingNotice"),
                    Title = LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Caption_CloseApp_ExecutingNotice"),
                };

                Window owner = Window.GetWindow(this);
                MessageBoxResult dlgResult = WpfMessageBox.Show(owner, ref msgProperties);

                if (dlgResult == MessageBoxResult.Yes)
                {
                    _executionService.Stop();
                }
                else if (dlgResult == MessageBoxResult.No)
                {
                    cea.Cancel = true;
                }
            }
        }

        private void executeStart(ExecuteStartEventArgs e)
        {
            this.Dispatcher.Invoke(() =>
            {
                setScriptReadOnly(true);
                //CommandManager.InvalidateRequerySuggested(); andy 2021.06.30 注销 影响片段执行
                var status = _executionService.GetCurrentStatus();
                if (ConfigService.CurrentSysConfig.IsDebugShowWindow && status != ExecuteStatus.DebugByStep)
                {
                    _windowService.MinimizeMainWindow();
                }
            }
            , System.Windows.Threading.DispatcherPriority.Normal);

            excuteLog("Execution Start");
        }

        private void executeEnd(ExecuteEndEventArgs e)
        {
            this.Dispatcher.Invoke(() =>
            {
                List<ScriptBase> scripts = new List<ScriptBase>();
                foreach (var item in this.tabCtrlFiles.Items)//查找 是否脚本已经被显示
                {
                    var tabitem = item as TabItem;
                    if (tabitem != null)
                    {
                        var script = (ScriptBase)tabitem.Tag;
                        scripts.Add(script);
                    }
                }

                _executionService.Finish(scripts);
                setScriptReadOnly(false);
                CommandManager.InvalidateRequerySuggested();
                lvTrackingInfo.ItemsSource = null;
                enumTrackingInfos.Clear();
                _windowService.ActivateWindows();

            }, System.Windows.Threading.DispatcherPriority.Normal);

            excuteLog("Execution End");
        }

        private void subScriptExecuteStart(SubScriptExecuteStartEventArgs e)
        {
            //日志记录到文件，不在UI显示 2021-06-21 Oliver add
            if (
                ConfigService.CurrentSysConfig.IsLogToFile
                || ConfigService.CurrentSysConfig.IsSilentExecution
                )
            {
                return;
            }

            this.Dispatcher.Invoke(() =>
            {
                excuteLog($"Load Engine [{e.ExecutionId}] [{e.ScriptPath}]");
            }
            , System.Windows.Threading.DispatcherPriority.Normal);
        }

        private void subScriptExecuteEnd(SubScriptExecuteEndEventArgs e)
        {
            //日志记录到文件，不在UI显示 2021-06-21 Oliver add
            if (
                ConfigService.CurrentSysConfig.IsLogToFile
                || ConfigService.CurrentSysConfig.IsSilentExecution
                )
            {
                return;
            }

            this.Dispatcher.Invoke(() =>
            {
                excuteLog($"Unload Engine [{e.ExecutionId}]");
            }
            , System.Windows.Threading.DispatcherPriority.Normal);
        }

        #region 调试
        private void debugTrack(FrameInfoBase stepInfo)
        {
            this.Dispatcher.Invoke(() =>
            {
                var trackingInfos = _executionService.DebugTrackInfo(stepInfo);

                if (trackingInfos != null)
                {
                    enumTrackingInfos = trackingInfos.ToList();
                    lvTrackingInfo.ItemsSource = trackingInfos.ToList();
                    searchTracking();
                }
            }
            , System.Windows.Threading.DispatcherPriority.Normal);
        }

        private void hitBreakpoint(HitBreakpointEventArgs e)
        {
            var status = _executionService.GetCurrentStatus();
            this.Dispatcher.Invoke(() =>
            {
                if (status == ExecuteStatus.Debuging)
                {
                    _windowService.ActivateWindows();
                }
            }, System.Windows.Threading.DispatcherPriority.Normal);

            Tuple<ScriptBase, bool> script = null;
            this.Dispatcher.Invoke(() =>
            {
                if (status != ExecuteStatus.Idle)
                {
                    var projectFile = ProjectManager.Instance.GetProjectFile(e.ScriptPath);
                    if (projectFile != null)
                    {
                        script = loadScript(projectFile);
                    }
                    else
                    {
                        script = loadSnippet(new SnippetFile()
                        {
                            Name = System.IO.Path.GetFileName(e.ScriptPath),
                            FullName = e.ScriptPath,
                        });
                    }

                    if (script.Item1 != null)
                    {
                        showScript(script.Item1);
                    }
                }
            }, System.Windows.Threading.DispatcherPriority.Normal);

            if (script != null)
            {
                if (!script.Item2)
                {
                    var timeSpan = 500;
                    if (script.Item1 is WorkflowScript)//andy 2021.06.30 workflow断点初始化比较耗时
                    {
                        timeSpan = 2000;
                    }
                    System.Threading.Thread.Sleep(TimeSpan.FromMilliseconds(timeSpan));//等待界面渲染完成 否则无法命中活动
                }
            }

            this.Dispatcher.Invoke(() =>
            {
                if (script != null && !String.IsNullOrWhiteSpace(e.Location))
                {
                    _executionService.DebugTrackLocation(script.Item1, e.Location);

                    if (!String.IsNullOrWhiteSpace(e.Verb) && e.Verb == "return")
                    {
                        script.Item1.ClearCurrentLocation();
                    }
                }
            }, System.Windows.Threading.DispatcherPriority.Normal);
        }

        private void txtSearchTracking_PreviewKeyUp(object sender, KeyEventArgs e)
        {
            searchTracking();
        }

        private void searchTracking()
        {
            TextBox txtSearchBox = WPFExtensionMethods.FindVisualChild<TextBox>(FindName("txtSearchTracking") as DependencyObject);
            if (lvTrackingInfo.ItemsSource == null || enumTrackingInfos.Count <= 0 || txtSearchBox == null)
                return;
            if (!string.IsNullOrWhiteSpace(txtSearchBox.Text))
                lvTrackingInfo.ItemsSource = enumTrackingInfos.Where(o => o.Name.ToLower().Contains(txtSearchBox.Text.ToLower())).ToList();
            else
                lvTrackingInfo.ItemsSource = enumTrackingInfos;
        }

        private void clearSearchTrackingTextBox()
        {
            TextBox txtSearchBox = WPFExtensionMethods.FindVisualChild<TextBox>(FindName("txtSearchTracking") as DependencyObject);
            txtSearchBox.Text = string.Empty;
        }

        private void clearTrackingSearchBtn_Click(object sender, RoutedEventArgs e)
        {
            clearSearchTrackingTextBox();
        }
        #endregion

        private void setScriptReadOnly(bool isReadOnly)
        {
            foreach (var item in this.tabCtrlFiles.Items)
            {
                var tabitem = item as CustomTabItem;
                if (tabitem != null)
                {
                    var script = (ScriptBase)tabitem.Tag;
                    tabitem.IsReadOnly = script is SnippetScript ? true : isReadOnly;
                    if (script is SnippetScript)
                    {
                        script?.SetReadOnly(true);
                    }
                    else
                    {
                        script?.SetReadOnly(isReadOnly);
                    }
                }
            }
        }

        private void showScript(ScriptBase script)
        {
            var isfind = false;//是否发现已经显示
            foreach (var item in this.tabCtrlFiles.Items)//查找 是否脚本已经被显示
            {
                var tabitem = item as TabItem;
                if (tabitem != null)
                {
                    var scriptShowed = (ScriptBase)tabitem.Tag;
                    if (scriptShowed == script)
                    {
                        isfind = true;
                        this.tabCtrlFiles.SelectedItem = tabitem;
                        break;
                    }
                }
            }

            if (!isfind) //如果未找到 展示脚本
            {
                if (script != null)
                {
                    var isReadOnly = _executionService.GetCurrentStatus() != ExecuteStatus.Idle;
                    if (isReadOnly)
                    {
                        script.SetReadOnly(true);
                    }
                    var item = new CustomTabItem() { IsSelected = true, Tag = script, Header = script.FileName, Content = script.ScriptEditor, IsReadOnly = script.IsReadOnly, FilePath = script.FilePath.ToString() };
                 
                    script.EditorContentChanged = (ea) => { item.IsContentChanged = true; };
                    this.tabCtrlFiles.Items.Add(item);
                }
            }
        }

        /// <summary>
        /// 显示脚本
        /// </summary>
        /// <param name="file"></param>
        private ScriptBase showScript(ProjectFile file, bool isSelected = true)
        {
            ScriptBase script = null;
            var isfind = false;//是否发现已经显示
            foreach (var item in this.tabCtrlFiles.Items)//查找 是否脚本已经被显示
            {
                var tabitem = item as TabItem;
                if (tabitem != null)
                {
                    script = (ScriptBase)tabitem.Tag;
                    isfind = file.FullName == script.FilePath;
                    if (isfind)//如果找到
                    {
                        tabitem.IsSelected = true;//展示此脚本
                        break;
                    }
                }
            }
            if (!isfind) //如果未找到 展示脚本
            {
                var projectDirectory = ProjectManager.Instance.CurrentProject.FullName;
                switch (file.Extension)
                {
                    case StaticResource.XamlExtension: script = new WorkflowScript(projectDirectory, file.FullName, file.IsStart); break;
                    default: return null;
                }

                script.BreakPointChanged = (e) =>
                {
                    if (e.Operation == Models.Enum.EBreakpointOper.Add)
                    {
                        _projectSettingService.AddBreakpoint(e.Breakpoint);
                    }
                    else if (e.Operation == Models.Enum.EBreakpointOper.Update)
                    {
                        _projectSettingService.UpdateBreakpoint(e.Breakpoint);
                    }
                    else if (e.Operation == Models.Enum.EBreakpointOper.Delete)
                    {
                        _projectSettingService.RemoveBreakpoint(e.Breakpoint);
                    }

                    _executionService.RefreshBreakpoints(script);
                };

                var breakpoints = _projectSettingService.GetBreakpoints(file.FullName);
                script.Load(breakpoints);

                if (script != null)
                {
                    var isReadOnly = _executionService.GetCurrentStatus() != ExecuteStatus.Idle;
                    if (isReadOnly)
                    {
                        script.SetReadOnly(true);
                    }
                    var item = new CustomTabItem() { IsSelected = isSelected, Tag = script, Header = script.FileName, Content = script.ScriptEditor, IsReadOnly = script.IsReadOnly, FilePath = script.FilePath.ToString() };
                   
                    script.EditorContentChanged = (ea) => { item.IsContentChanged = true; };
                    this.tabCtrlFiles.Items.Add(item);
                }
            }

            return script;
        }

        /// <summary>
        /// 加载脚本
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        private Tuple<ScriptBase, bool> loadScript(ProjectFile file)
        {
            ScriptBase script = null;
            var isfind = false;//是否发现已经显示
            foreach (var item in this.tabCtrlFiles.Items)//查找 是否脚本已经被显示
            {
                var tabitem = item as TabItem;
                if (tabitem != null)
                {
                    script = (ScriptBase)tabitem.Tag;
                    isfind = file.FullName == script.FilePath;
                    if (isfind)//如果找到
                    {
                        break;
                    }
                }
            }

            if (!isfind) //如果未找到 展示脚本
            {
                var projectDirectory = ProjectManager.Instance.CurrentProject.FullName;
                switch (file.Extension)
                {
                    case StaticResource.XamlExtension: script = new WorkflowScript(projectDirectory, file.FullName, file.IsStart); break;
                    default: return null;
                }

                script.BreakPointChanged = (e) =>
                {
                    if (e.Operation == Models.Enum.EBreakpointOper.Add)
                    {
                        _projectSettingService.AddBreakpoint(e.Breakpoint);
                    }
                    else if (e.Operation == Models.Enum.EBreakpointOper.Update)
                    {
                        _projectSettingService.UpdateBreakpoint(e.Breakpoint);
                    }
                    else if (e.Operation == Models.Enum.EBreakpointOper.Delete)
                    {
                        _projectSettingService.RemoveBreakpoint(e.Breakpoint);
                    }

                    _executionService.RefreshBreakpoints(script);
                };

                var breakpoints = _projectSettingService.GetBreakpoints(file.FullName);
                script.Load(breakpoints);
            }

            return new Tuple<ScriptBase, bool>(script, isfind);
        }

        /// <summary>
        /// 清理脚本当前位置
        /// </summary>
        private void clearScriptCurrentLocation()
        {
            foreach (var item in this.tabCtrlFiles.Items)
            {
                var tabitem = item as TabItem;
                if (tabitem != null)
                {
                    var script = (ScriptBase)tabitem.Tag;
                    script?.ClearCurrentLocation();
                }
            }
        }

        /// <summary>
        /// 追踪终结的脚本
        /// </summary>
        /// <param name="e"></param>
        private void trackTerminalScript(ScriptExcuteUnhandledExceptionEventArgs e)
        {
            var status = _executionService.GetCurrentStatus();
            this.Dispatcher.Invoke(() =>
            {
                _windowService.ActivateWindows();

            }, System.Windows.Threading.DispatcherPriority.Normal);

            Tuple<ScriptBase, bool> terminalScript = null;
            this.Dispatcher.Invoke(() =>
            {
                if (status != ExecuteStatus.Idle)
                {
                    var projectFile = ProjectManager.Instance.GetProjectFile(e.ScriptPath);
                    if (projectFile != null)
                    {
                        terminalScript = loadScript(projectFile);
                    }
                    else
                    {
                        terminalScript = loadSnippet(new SnippetFile()
                        {
                            Name = System.IO.Path.GetFileName(e.ScriptPath),
                            FullName = e.ScriptPath,
                        });
                    }

                    if (terminalScript.Item1 != null)
                    {
                        showScript(terminalScript.Item1);
                    }
                }
            }, System.Windows.Threading.DispatcherPriority.Normal);

            if (!terminalScript.Item2)
            {
                var timeSpan = 1000;
                System.Threading.Thread.Sleep(TimeSpan.FromMilliseconds(timeSpan));//等待界面渲染完成 否则无法命中活动
            }

            this.Dispatcher.Invoke(() =>
            {
                if (terminalScript != null && !String.IsNullOrWhiteSpace(e.Location))
                {
                    _executionService.Terminate(terminalScript.Item1, e.Location);
                }
            }, System.Windows.Threading.DispatcherPriority.Normal);
        }

        private void outputMsg(TagEventArgs<string> e)
        {
            excuteTrace(new ScriptExecuteTrackEventArgs(e.Tag));
        }

        private void TrackInfoDetail_Click(object sender, RoutedEventArgs e)
        {
            var btn = sender as Button;
            if (btn != null)
            {
                var info = btn.Tag.ToString();
                if (!String.IsNullOrWhiteSpace(info))
                {
                    var debugView = new WindowDebugView(info);
                    debugView.Owner = App.Current.MainWindow; ;
                    debugView.ShowDialog();
                }
            }
        }

        /// <summary>
        /// 展示片段文件（只读）
        /// </summary>
        /// <param name="e"></param>
        /// <returns></returns>
        private void showSnippetScript(TagEventArgs<SnippetFile> e)
        {
            this.Dispatcher.Invoke(() =>
            {
                var script = loadSnippet(e.Tag);
                if (script.Item1 != null)
                {
                    showScript(script.Item1);
                }
            }, System.Windows.Threading.DispatcherPriority.Normal);
        }

        private Tuple<ScriptBase, bool> loadSnippet(SnippetFile snippet)
        {
            ScriptBase script = null;
            var isfind = false;//是否发现已经显示
            if (snippet.Extension == StaticResource.XamlExtension)
            {
                foreach (var item in this.tabCtrlFiles.Items)//查找 是否脚本已经被显示
                {
                    var tabitem = item as TabItem;
                    if (tabitem != null)
                    {
                        script = (ScriptBase)tabitem.Tag;
                        isfind = snippet.FullName == script.FilePath;
                        if (isfind)//如果找到
                        {
                            break;
                        }
                    }
                }

                if (!isfind) //如果未找到 展示脚本
                {
                    var projectDirectory = ProjectManager.Instance.CurrentProject.FullName;
                    script = new SnippetScript(projectDirectory, snippet.FullName);
                    script.Load();
                    script.SetReadOnly(true);
                }
            }

            return new Tuple<ScriptBase, bool>(script, isfind);
        }

        #region 校验
        private void validateScripts(TagEventArgs<string> e)
        {
            allScriptSave(EventArgs.Empty);

            var _projectManager = ProjectManager.Instance;

            var validateModel = _projectManager.ValidateScriptALL(e.Tag);

            if (validateModel != null)
            {
                this.tItemErrorInfo.IsSelected = true;
                lvErrorInfo.ItemsSource = validateModel.ToList();
            }
        }

        private void lvErrorInfo_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            var validationErrorInfo = this.lvErrorInfo.SelectedItem as ValidationErrorInfo;
            if (validationErrorInfo == null)
                return;
            Tuple<ScriptBase, bool> script = null;

            var projectFile = ProjectManager.Instance.GetProjectFile(validationErrorInfo.FullName);
            if (projectFile != null)
            {
                script = loadScript(projectFile);
            }

            if (script.Item1 != null)
            {
                showScript(script.Item1);
            }

            if (script.Item1 != null && !String.IsNullOrWhiteSpace(validationErrorInfo.ActivityParentIdRef))
            {
                _searchService.FocusActivityByIdRef(script.Item1, validationErrorInfo.ActivityParentIdRef);
            }
        }

        #endregion

        #region 断点
        private void loadLvBreakPoint(EventArgs eventArgs)
        {
            this.Dispatcher.Invoke(() =>
            {
                _obsBreakPoints.Clear();
                var scripts = new List<ScriptBase>();
                foreach (var item in this.tabCtrlFiles.Items)//查找 是否脚本已经被显示
                {
                    var tabitem = item as TabItem;
                    if (tabitem != null)
                    {
                        if (System.IO.Path.GetExtension(((ScriptBase)tabitem.Tag).FileName) == StaticResource.XamlExtension)
                        {
                            var breakpoints = ((ScriptBase)tabitem.Tag).GetBreakpoints();
                            _projectSettingService.RefreshBreakpoints(((ScriptBase)tabitem.Tag).FilePath, breakpoints);
                        }
                        scripts.Add((ScriptBase)tabitem.Tag);
                    }
                }
                IEnumerable<Breakpoint> listBreakpoints = _projectSettingService.GetBreakpointsAll(scripts);
                if (listBreakpoints != null)
                {
                    listBreakpoints.ToList().ForEach(breakPoint => _obsBreakPoints.Add(new Breakpoint()
                    {
                        BreakpointType = breakPoint.BreakpointType,
                        BreakpointViewTypeUri = breakPoint.BreakpointViewTypeUri,
                        Path = breakPoint.Path,
                        FileName = breakPoint.FileName,
                        ActivityType = breakPoint.ActivityType,
                        ActivityId = breakPoint.ActivityId,
                        ActivityName = string.IsNullOrWhiteSpace(breakPoint.ActivityName) ? (int.Parse(breakPoint.Location) + 1).ToString() : breakPoint.ActivityName,
                        Location = breakPoint.Location,
                        IsEnabled = breakPoint.IsEnabled,
                        RefId = breakPoint.RefId,

                    }));
                }
            }, System.Windows.Threading.DispatcherPriority.Normal);
        }
        /// <summary>
        /// 双击定位断点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lvBreakPoint_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            var breakPoint = this.lvBreakPoint.SelectedItem as Breakpoint;
            if (breakPoint == null)
                return;
            Tuple<ScriptBase, bool> script = null;

            var projectFile = ProjectManager.Instance.GetProjectFile(breakPoint.Path);
            if (projectFile != null)
            {
                script = loadScript(projectFile);
            }

            if (script.Item1 != null)
            {
                showScript(script.Item1);
            }

            if (projectFile.Extension == StaticResource.XamlExtension)
            {
                if (script.Item1 != null && !String.IsNullOrWhiteSpace(breakPoint.ActivityId))
                {
                    _executionService.ActivitySelectionById(script.Item1, breakPoint.ActivityId);
                }
            }
        }
        /// <summary>
        /// 启用断点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void enableBreakPoint_Click(object sender, RoutedEventArgs e)
        {
            var breakPoints = _projectSettingService.UpdateBreakpointAll(true);
            foreach (var item in this.tabCtrlFiles.Items)//查找 是否脚本已经被显示
            {
                var tabitem = item as TabItem;
                if (tabitem != null)
                {
                    ((ScriptBase)tabitem.Tag).EnableBreakPoint(breakPoints);
                }
            }
            loadLvBreakPoint(EventArgs.Empty);
        }
        /// <summary>
        /// 禁用断点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void disableBreakPoint_Click(object sender, RoutedEventArgs e)
        {
            var breakPoints = _projectSettingService.UpdateBreakpointAll(false);
            foreach (var item in this.tabCtrlFiles.Items)//查找 是否脚本已经被显示
            {
                var tabitem = item as TabItem;
                if (tabitem != null)
                {
                    ((ScriptBase)tabitem.Tag).BoundedBreakPoint(breakPoints);
                }
            }
            loadLvBreakPoint(EventArgs.Empty);
        }
        /// <summary>
        /// 删除选中断点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void deleteBreakPoint_Click(object sender, RoutedEventArgs e)
        {
            var breakPoint = this.lvBreakPoint.SelectedItem as Breakpoint;
            if (breakPoint != null)
            {
                _projectSettingService.RemoveBreakpoint(breakPoint);
            }
            else
            {
                return;
            }

            foreach (var item in this.tabCtrlFiles.Items)//查找 是否脚本已经被显示
            {
                var tabitem = item as TabItem;
                if (tabitem != null)
                {
                    if (((ScriptBase)tabitem.Tag).FilePath == breakPoint.Path)
                    {
                        ((ScriptBase)tabitem.Tag).DeleteBreakPoint(breakPoint);
                    }
                }
            }
            loadLvBreakPoint(EventArgs.Empty);
        }
        /// <summary>
        /// 删除所有断点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void deleteAllBreakPoint_Click(object sender, RoutedEventArgs e)
        {
            var scripts = new List<ScriptBase>();
            foreach (var item in this.tabCtrlFiles.Items)//查找 是否脚本已经被显示
            {
                var tabitem = item as TabItem;
                if (tabitem != null)
                {
                    scripts.Add((ScriptBase)tabitem.Tag);
                }
            }
            IEnumerable<Breakpoint> breakpoints = _projectSettingService.GetBreakpointsAll(scripts);
            _projectSettingService.RemoveAllBreakpoints();

            foreach (var item in this.tabCtrlFiles.Items)//查找 是否脚本已经被显示
            {
                var tabitem = item as TabItem;
                if (tabitem != null)
                {
                    ((ScriptBase)tabitem.Tag).DeleteAllBreakPoints(breakpoints);
                }
            }
            loadLvBreakPoint(EventArgs.Empty);
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            if (!DesignerProperties.GetIsInDesignMode(this))
            {
                GlobalActionHandler.BreakPointFresh += loadLvBreakPoint;
                loadLvBreakPoint(EventArgs.Empty);
            }
        }
        #endregion

        #region 工程参数
        private void setPutParam(TagEventArgs<ProjectParam, int> e)
        {
            Tuple<ScriptBase, bool> script = null;
            var name = System.IO.Path.Combine(ProjectManager.Instance.CurrentProject.FullName, StaticResource.ProjectSelfFile, StaticResource.ProjectStart);

            var projectFile = ProjectManager.Instance.GetProjectFile(name);
            if (projectFile != null)
            {
                script = loadScript(projectFile);
            }

            if (script.Item1 != null)
            {
                showScript(script.Item1);
            }

            if (script.Item1 != null)
            {
                if (e.Tag2 == 0)//in类型
                {
                    ((WorkflowScript)script.Item1).SetInArgument(e.Tag1);
                }
                else if (e.Tag2 == 1)//out类型
                {
                    ((WorkflowScript)script.Item1).SetOutArgument(e.Tag1);
                }
            }
            GlobalActionHandler.AllScriptSave?.Invoke(EventArgs.Empty);
            var btn = new Button();
            btn.Tag = name;
            
            this.CloseTab_Click(btn, new RoutedEventArgs());
            if (projectFile != null)
            {
                script = loadScript(projectFile);
            }

            if (script.Item1 != null)
            {
                showScript(script.Item1);
            }
        }
        private void setPutParams(TagEventArgs<List<ProjectParam>> e)
        {
            Tuple<ScriptBase, bool> script = null;
            var name = System.IO.Path.Combine(ProjectManager.Instance.CurrentProject.FullName, StaticResource.ProjectSelfFile, StaticResource.ProjectStart);

            var projectFile = ProjectManager.Instance.GetProjectFile(name);
            if (projectFile != null)
            {
                script = loadScript(projectFile);
            }

            if (script.Item1 != null)
            {
                showScript(script.Item1);
            }

            if (script.Item1 != null)
            {
                ((WorkflowScript)script.Item1).SetChangeArgument(e.Tag);
            }
            GlobalActionHandler.AllScriptSave?.Invoke(EventArgs.Empty);
            var btn = new Button();
            btn.Tag = name;
            this.CloseTab_Click(btn, new RoutedEventArgs());
            if (projectFile != null)
            {
                script = loadScript(projectFile);
            }

            if (script.Item1 != null)
            {
                showScript(script.Item1);
            }
        }
        private void loadPutParam(ArgumentEventArgs eventArgs)
        {
            var paramList = _projectParamDetailSerivce.GetProjectParamDetail();
            var inprojectParams = new List<ProjectParam>();
            var outprojectParams = new List<ProjectParam>();
            bool isChange = false;
            foreach (var item in eventArgs.Arguments)
            {
                foreach (var inParam in paramList.Input)
                {
                    if (item.Name == inParam.Name)
                    {
                        if (item.ParamType != inParam.ParamType || item.Value != inParam.Value)
                        {
                            inprojectParams.Add(new ProjectParam()
                            {
                                Name = item.Name,
                                ParamType = item.ParamType,
                                Value = item.Value,
                                Description = inParam.Description
                            });
                            isChange = true;
                        }
                        else
                        {
                            inprojectParams.Add(inParam);
                        }
                    }
                }
                foreach (var outParam in paramList.Output)
                {
                    if (item.Name == outParam.Name)
                    {
                        if (item.ParamType != outParam.ParamType)
                        {
                            outprojectParams.Add(new ProjectParam()
                            {
                                Name = item.Name,
                                ParamType = item.ParamType,
                                Value = item.Value,
                                Description = outParam.Description
                            });
                            isChange = true;
                        }
                        else
                        {
                            outprojectParams.Add(outParam);
                        }
                    }
                }
            }
            if ((paramList.Input.Count + paramList.Output.Count) != (inprojectParams.Count + outprojectParams.Count) || isChange)
            {
                WPFExtensionMethods.ShowDelayMessage(LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Caption_CloseApp_ExecutingNotice"), LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Msg_ParamsChange"));
                paramList.Input = inprojectParams;
                paramList.Output = outprojectParams;
                _projectParamDetailSerivce.SaveProjectParamDetail(paramList);
            }
        }

        #endregion

        #region 标签右键
        /// <summary>
        /// 全部关闭
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tabCtrlCloseAll_Click(object sender, RoutedEventArgs e)
        {
            bool isSave = true;
            foreach (TabItem tabItem in this.tabCtrlFiles.Items)
            {
                var script = (ScriptBase)tabItem.Tag;
                if (script != null)
                {
                    if (script.IsEditorContentChanged && isSave)
                    {
                        var msgProperties = new WpfMessageBoxProperties()
                        {
                            Button = MessageBoxButton.YesNoCancel,
                            ButtonYesText = LocalizationProvider.GetLocalizedString("MessageBox_Button_Yes"),
                            ButtonNoText = LocalizationProvider.GetLocalizedString("MessageBox_Button_No"),
                            ButtonCancelText = LocalizationProvider.GetLocalizedString("MessageBox_Button_Cancel"),
                            Image = MessageBoxImage.Question,
                            Text = LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Msg_SaveAllFile"),
                            Title = LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Caption_SaveFile"),
                        };

                        Window owner = Window.GetWindow(this);
                        MessageBoxResult dlgResult = WpfMessageBox.Show(owner, ref msgProperties);

                        if (dlgResult == MessageBoxResult.Yes)
                        {
                            GlobalActionHandler.AllScriptSave?.Invoke(EventArgs.Empty);
                            isSave = false;
                        }
                        else if (dlgResult == MessageBoxResult.No)
                        {
                            isSave = false;
                        }
                        else if (dlgResult == MessageBoxResult.Cancel)
                        {
                            return;
                        }
                    }
                }
            }
            foreach (TabItem tabItem in this.tabCtrlFiles.Items)
            {
                var script = (ScriptBase)tabItem.Tag;
                if (script != null)
                {
                    script.Dispose();//释放脚本 
                }
            }
            this.tabCtrlFiles.Items.Clear();

            if (this.tabCtrlFiles.Items.Count == 0)
            {
                GlobalActionHandler.ScriptSelected?.Invoke(new TagEventArgs<ScriptBase>(null));
            }
        }
        /// <summary>
        /// 关闭其他页面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tabCtrlCloseOther_Click(object sender, RoutedEventArgs e)
        {
            var menuItem = WPFExtensionMethods.VisualUpwardSearch<MenuItem>(e.OriginalSource as DependencyObject) as MenuItem;
            if (menuItem != null)
            {
                var btnItem = menuItem.TemplatedParent as CustomTabItem;
                List<TabItem> clearTabItems = new List<TabItem>();
                bool isSave = true;
                foreach (TabItem tabItem in this.tabCtrlFiles.Items)
                {
                    var script = (ScriptBase)tabItem.Tag;
                    if (script != null && script.FilePath.ToString() != btnItem.FilePath.ToString())
                    {
                        if (script.IsEditorContentChanged && isSave)
                        {
                            var msgProperties = new WpfMessageBoxProperties()
                            {
                                Button = MessageBoxButton.YesNoCancel,
                                ButtonYesText = LocalizationProvider.GetLocalizedString("MessageBox_Button_Yes"),
                                ButtonNoText = LocalizationProvider.GetLocalizedString("MessageBox_Button_No"),
                                ButtonCancelText = LocalizationProvider.GetLocalizedString("MessageBox_Button_Cancel"),
                                Image = MessageBoxImage.Question,
                                Text = LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Msg_SaveAllFile"),
                                Title = LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Caption_SaveFile"),
                            };

                            Window owner = Window.GetWindow(this);
                            MessageBoxResult dlgResult = WpfMessageBox.Show(owner, ref msgProperties);

                            if (dlgResult == MessageBoxResult.Yes)
                            {
                                GlobalActionHandler.AllScriptSave?.Invoke(EventArgs.Empty);
                                isSave = false;
                            }
                            else if (dlgResult == MessageBoxResult.No)
                            {
                                isSave = false;
                            }
                            else if (dlgResult == MessageBoxResult.Cancel)
                            {
                                return;
                            }
                        }
                        clearTabItems.Add(tabItem);
                    }
                }
                foreach (TabItem tabItem in clearTabItems)
                {
                    var script = (ScriptBase)tabItem.Tag;
                    if (script != null)
                    {
                        script.Dispose();//释放脚本 
                    }
                    this.tabCtrlFiles.Items.Remove(tabItem);
                }

                if (this.tabCtrlFiles.Items.Count == 0)
                {
                    GlobalActionHandler.ScriptSelected?.Invoke(new TagEventArgs<ScriptBase>(null));
                }
            }
        }
        /// <summary>
        /// 关闭当前页面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tabCtrlClose_Click(object sender, RoutedEventArgs e)
        {
            var menuItem = WPFExtensionMethods.VisualUpwardSearch<MenuItem>(e.OriginalSource as DependencyObject) as MenuItem;
            if (menuItem != null)
            {
                var btnItem = menuItem.TemplatedParent as CustomTabItem;
                foreach (TabItem tabItem in this.tabCtrlFiles.Items)
                {
                    var script = (ScriptBase)tabItem.Tag;
                    if (script != null)
                    {
                        if (script.FilePath.ToString() == btnItem.FilePath.ToString())
                        {
                            if (script.IsEditorContentChanged)
                            {
                                var msgProperties = new WpfMessageBoxProperties()
                                {
                                    Button = MessageBoxButton.YesNoCancel,
                                    ButtonYesText = LocalizationProvider.GetLocalizedString("MessageBox_Button_Yes"),
                                    ButtonNoText = LocalizationProvider.GetLocalizedString("MessageBox_Button_No"),
                                    ButtonCancelText = LocalizationProvider.GetLocalizedString("MessageBox_Button_Cancel"),
                                    Image = MessageBoxImage.Question,
                                    Text = LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Msg_SaveFile"),
                                    Title = LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Caption_SaveFile"),
                                };

                                Window owner = Window.GetWindow(this);
                                MessageBoxResult dlgResult = WpfMessageBox.Show(owner, ref msgProperties);

                                if (dlgResult == MessageBoxResult.Yes)
                                {
                                    GlobalActionHandler.AllScriptSave?.Invoke(EventArgs.Empty);
                                }
                                else if (dlgResult == MessageBoxResult.No)
                                {

                                }
                                else if (dlgResult == MessageBoxResult.Cancel)
                                {
                                    return;
                                }
                            }
                            script.Dispose();//释放脚本  
                            this.tabCtrlFiles.Items.Remove(tabItem);
                            break;
                        }
                    }
                }

                if (this.tabCtrlFiles.Items.Count == 0)
                {
                    GlobalActionHandler.ScriptSelected?.Invoke(new TagEventArgs<ScriptBase>(null));
                }
            }
        }
        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tabCtrlSave_Click(object sender, RoutedEventArgs e)
        {
            bool result = false;
            var menuItem = WPFExtensionMethods.VisualUpwardSearch<MenuItem>(e.OriginalSource as DependencyObject) as MenuItem;
            if (menuItem != null)
            {
                var tabitem = menuItem.TemplatedParent as CustomTabItem;

                if (tabitem != null)
                {
                    if (tabitem.IsContentChanged)
                    {
                        var script = tabitem.Tag as ScriptBase;
                        if (script != null)
                        {
                            string msg;
                            result = script.TrySave(out msg);
                            if (result)
                            {
                                var breakpoints = script.GetBreakpoints();
                                _projectSettingService.RefreshBreakpoints(script.FilePath, breakpoints);

                                tabitem.IsContentChanged = false;
                            }
                            else
                            {
                                excuteTrace(new ScriptExecuteTrackEventArgs(msg));
                                var msgProperties1 = new WpfMessageBoxProperties()
                                {
                                    Button = MessageBoxButton.OK,
                                    ButtonOkText = LocalizationProvider.GetLocalizedString("MessageBox_Button_OK"),
                                    Image = MessageBoxImage.Error,
                                    Text = LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Msg_SaveFile_Error"),
                                    Title = LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_MsgBox_Caption_SaveFile"),
                                };
                                Window owner = Window.GetWindow(this);
                                WpfMessageBox.Show(owner, ref msgProperties1);
                            }
                        }
                    }
                }
            }

            if (result)
            {
                if (GlobalActionHandler.SetStatusBarMsg != null)
                {
                    GlobalActionHandler.SetStatusBarMsg(new TagEventArgs<string>(LocalizationProvider.GetLocalizedString("UCtrlDesignRegion_StatusBar_Msg_SaveFile")));
                }
            }
            loadLvBreakPoint(EventArgs.Empty);
        }
        /// <summary>
        /// 打开文件所在路径
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tabCtrlOpenFolder_Click(object sender, RoutedEventArgs e)
        {
            var menuItem = WPFExtensionMethods.VisualUpwardSearch<MenuItem>(e.OriginalSource as DependencyObject) as MenuItem;
            if (menuItem != null)
            {
                var tabitem = menuItem.TemplatedParent as CustomTabItem;

                if (tabitem != null)
                {
                    var script = tabitem.Tag as ScriptBase;
                    if (script != null)
                    {
                        var path = script.FilePath.Replace(script.FileName, "");
                        if (FileHelper.CheckFolderExisting(path))
                        {
                            System.Diagnostics.Process.Start("Explorer.exe", path);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 复制文件名
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tabCtrlCopyName_Click(object sender, RoutedEventArgs e)
        {
            var menuItem = WPFExtensionMethods.VisualUpwardSearch<MenuItem>(e.OriginalSource as DependencyObject) as MenuItem;
            if (menuItem != null)
            {
                var btnItem = menuItem.TemplatedParent as CustomTabItem;
                Clipboard.SetDataObject(btnItem.Header.ToString());
            }
        }
        #endregion

        #region 日志窗口收起弹出
        private void btnMiniOrMaxLogTab(EventArgs e)
        {
            if (btnMaximizeTab.Visibility == Visibility.Visible)
            {
                btnMaximizeTab_Click(new object(), new RoutedEventArgs());
            }
            else
            {
                btnMinimizeTab_Click(new object(), new RoutedEventArgs());
            }
        }
        private void btnMinimizeTab_Click(object sender, RoutedEventArgs e)
        {
            if (buttomTabitem.Height.Value < 100)
            {
                buttomTabitem.Height = new GridLength(300);
            }
            else
            {
                _lastButtomTabitemHight = buttomTabitem.Height.Value;
                buttomTabitem.Height = new GridLength(30);
                btnMinimizeTab.Visibility = Visibility.Collapsed;
                btnMaximizeTab.Visibility = Visibility.Visible;
            }
        }

        private void btnMaximizeTab_Click(object sender, RoutedEventArgs e)
        {
            if (_lastButtomTabitemHight < 100)
            {
                _lastButtomTabitemHight = 300;
                buttomTabitem.Height = new GridLength(300);
                btnMinimizeTab.Visibility = Visibility.Visible;
                btnMaximizeTab.Visibility = Visibility.Collapsed;
            }
            else
            {
                buttomTabitem.Height = new GridLength(_lastButtomTabitemHight);
                btnMinimizeTab.Visibility = Visibility.Visible;
                btnMaximizeTab.Visibility = Visibility.Collapsed;
            }
        }
        #endregion
    }
}
